#ifndef __BALLADE_UTIL_LOGGER_H__
#define __BALLADE_UTIL_LOGGER_H__

#include <iostream>
#include <string>

#include <ballade/util/config.h>

namespace Ballade
{
	
	namespace Util
	{
		using std::ostream;
		using std::string;
		
		class UTIL_API Logger
		{
		public:
			
			enum Level
			{
				DEBUG_,
					INFO_,
					WARN_,
					ERROR_,
					FATAL_
			};
			
			~Logger();
			
			static Logger &getInstance();
			static Logger &getInstance(const string &logFile);
			
			void destroy();
			void close();
			
			void setLevel(const Level level);
			
			bool isDebugEnabled()	const;
			bool isInfoEnabled()	const;
			bool isWarnEnabled()	const;
			bool isErrorEnabled()	const;
			bool isFatalEnabled()	const;
			
			void debug(const char *fmt, ...);
			void info(const char *fmt, ...);
			void warn(const char *fmt, ...);
			void error(const char *fmt, ...);
			void fatal(const char *fmt, ...);
			
		protected:	
			
#define MAX_LOG_LINE 1024 * 100
			
			Logger();
			Logger(const string &logFile);
			
			void setOutputStream(ostream *os);
			
			static int ReferenceNum;
			
		private:
			
			char _buf[MAX_LOG_LINE];
			
			void doLog(const Level level, const char *fmt, va_list ap);
			string createHeader(const Level level);
			
			ostream *_os;
			
			static Level Level_;
			static bool UseStdout;
			static bool IsBusy;
			static Logger *Instance;
		};
	}
}

#endif